
import "mars3d/dist/mars3d.css"
import "mars3d-cesium/Build/Cesium/Widgets/widgets.css"
import * as mars3d from "mars3d"

import { Mars3DRender } from './Mars3dRender.jsx'
import { CommonSceneUrl } from '../Config/urlList.jsx'
import { initData, layerList, specialMap } from "./Params"


// 初始化mars函数element
export const Initialization = (DIV, config, data) => {
    const map = new mars3d.Map(DIV, initData)
    const gra = new mars3d.layer.GraphicLayer({ isEditing: true })
    const clip = new mars3d.thing.TerrainClip({ czm: false })
    new mars3d.Token.updateGaode('86933efc2c60baa40afa26b746ff81b9')
    effectOn(map)
    map.addLayer(gra)
    map.addThing(clip)
    SetConfig(map, gra, clip, config)
    data && Mars3DRender({ map, gra, clip, data })
    return { map, gra, clip }
}

export const SetConfig = (map, gra, clip, config) => {
    InitFitA01(map, config.FitA01)
    InitFitA02(map, config.FitA02)
    InitFitA03(map, config.FitA03)
    InitFitA04(map, config.FitA04)
    InitFitA05(map, config.FitA05)
    InitFitA06(map, config.FitA06)
    InitFitA07(gra, clip, config.FitA07)
    InitOthA01(map, config.OthA01)
}


// 初始化基础图层
const InitFitA01 = (map, params) => {
    map.setSceneOptions(params)
}

const InitFitA02 = (map, params) => {
    map.setSceneOptions({ globe: params })
}

const InitFitA03 = (map, params) => {
    map.basemap = params.basemap
    map.setLayersOptions(LayerListMap(params.layer))
    map.setSceneOptions({ globe: { baseColor: params.baseColor } })
}
// 遍历辅助图层
export const LayerListMap = (arr) => {
    return layerList.map(item => {
        const isItemInValue = arr.includes(item.id)
        const show = isItemInValue ? true : false
        return { ...item, show }
    })
}


const InitFitA04 = (map, params) => {
    map.setSceneOptions({ cameraController: params })
}

const InitFitA05 = (map, params) => {
    Object.keys(params).forEach(key => map.controls[key].show = params[key])
}

const InitFitA06 = (map, params) => {
    map.effects.nightVision.enabled = params.nightVisionEffect
    map.effects.mosaic.enabled = params.mosaicEffect
    map.effects.blackAndWhite.enabled = params.blackAndWhiteEffect
    map.effects.blackAndWhite.gradations = params.gradations

    map.effects.depthOfField.enabled = params.depthOfField
    map.effects.depthOfField.focalDistance = params.depthFocalDistance
    map.effects.depthOfField.delta = params.depthDelta
    map.effects.depthOfField.sigma = params.depthSigma
    map.effects.depthOfField.stepSize = params.depthStepSize

    map.effects.bloom.enabled = params.bloomEffect
    map.effects.bloom.contrast = params.bloomContrast
    map.effects.bloom.brightness = params.bloomBrightness
    map.effects.bloom.delta = params.bloomDelta
    map.effects.bloom.sigma = params.bloomSigma
    map.effects.bloom.stepSize = params.bloomStepSize

    map.effects.brightness.enabled = params.brightnessEffect
    map.effects.brightness.brightness = params.brightness

    map.effects.fog.enabled = params.fogEffect
    map.effects.fog.fogByDistance.x = params.fogByDistance_near
    map.effects.fog.fogByDistance.z = params.fogByDistance_far
    map.effects.fog.maxHeight = params.fogMaxHeight

    map.effects.rain.enabled = params.rainEffect
    map.effects.rain.size = params.rainSize
    map.effects.rain.speed = params.rainSpeed
    map.effects.rain.direction = params.rainDirection

    map.effects.snow.enabled = params.snowEffect
    map.effects.snow.speed = params.snowSpeed
    map.effects.snow.maxHeight = params.snowMaxHeight

    map.effects.snowCover.enabled = params.snowCover
    map.effects.snowCover.alpha = params.snowCoverAlpha
    map.effects.snowCover.maxHeight = params.snowCoverMaxHeight

    map.effects.outline.enabled = params.outlineEffect
    map.effects.outline.color = params.outlineColor
    map.effects.outline.colorHidden = params.outlineColorHidden
    map.effects.outline.width = params.outlineWidth
    map.effects.outline.showPlane = params.outlineShowPlane
    map.effects.outline.planeAngle = params.outlinePlaneAngle
    map.effects.outline.glow = params.outlineGlow
    map.effects.outline.glowPower = params.outlineGlowPower
    map.effects.outline.glowStrength = params.outlineGlowStrength

    map.effects.bloomTarget.enabled = params.bloomTargetEffect
    map.effects.bloomTarget.color = params.bloomTargetColor
    map.effects.bloomTarget.brightness = params.bloomTargetBrightness
    map.effects.bloomTarget.ratio = params.bloomTargetRatio
    map.effects.bloomTarget.smoothWidth = params.bloomTargetSmoothWidth
    map.effects.bloomTarget.threshole = params.bloomTargetThreshole
    map.effects.bloomTarget.contrast = params.bloomTargetContrast
    map.effects.bloomTarget.blurSamples = params.bloomTargetBlurSamples
    map.effects.bloomTarget.stepSize = params.bloomTargetStepSize
    map.effects.bloomTarget.delta = params.bloomTargetDelta
    map.effects.bloomTarget.sigma = params.bloomTargetSigma
}

const InitFitA07 = (gra, clip, params) => {
    ClearGra(gra, clip)
    const { mapTiles, isClip, cove, line, wall } = params
    mapTiles.length !== 0 && mapTiles.forEach(item => {
        GetUrlData(item).then(res => {
            const arr = mars3d.Util.geoJsonToGraphics(res)
            clipFunc(arr, isClip, clip)
            coveFunc(arr, cove, gra)
            lineFunc(arr, line, gra)
            wallFunc(arr, wall, gra)
        })
    })
}

const clipFunc = (arr, isClip, clip) => {
    if (isClip) {
        arr.forEach(({ attr, positions }) => {
            setTimeout(() => {
                if (specialMap.includes(attr.adcode)) {
                    positions.forEach(key => {
                        clip.addArea(key)
                        clip.clipOutSide = true
                    })
                } else {
                    clip.addArea(positions)
                    clip.clipOutSide = true
                }
            }, 1)
        })
    } else {
        clip.clear()
    }
}

const coveFunc = (arr, cove, gra) => {
    const { isEnabled, ...style } = cove
    if (isEnabled) {
        const renderDemo = (positions) => {
            const graphic = new mars3d.graphic.PolygonPrimitive({ positions, attr: 'Coverage', style })
            gra.addGraphic(graphic)
        }

        arr.forEach(({ attr, positions }) => {
            if (specialMap.includes(attr.adcode)) positions.forEach(key => renderDemo(key))
            else renderDemo(positions)
        })
    }
}
const lineFunc = (arr, line, gra) => {
    const { isEnabled, ...style } = line
    if (isEnabled) {
        const renderDemo = (positions) => {
            const polyline = new mars3d.graphic.PolylineEntity({ attr: 'BoundaryLine', positions, style })
            gra.addGraphic(polyline)
        }
        arr.forEach(({ attr, positions }) => {
            if (specialMap.includes(attr.adcode)) positions.forEach(key => renderDemo(key))
            else renderDemo(positions)
        })
    }
}
const wallFunc = (arr, wall, gra) => {
    const { isEnabled, ...style } = wall
    if (isEnabled) {
        const renderDemo = (positions) => {
            const Wall = new mars3d.graphic.WallPrimitive({ attr: 'BoundaryWall', positions, style })
            gra.addGraphic(Wall)
        }
        arr.forEach(({ attr, positions }) => {
            if (specialMap.includes(attr.adcode)) positions.forEach(key => renderDemo(key))
            else renderDemo(positions)
        })
    }
}


const ClearGra = (gra, clip) => {
    clip.clear()
    ClearBaseFunc(gra, 'Coverage')
    ClearBaseFunc(gra, 'BoundaryLine')
    ClearBaseFunc(gra, 'BoundaryWall')
}

const ClearBaseFunc = (Gra, value) => {
    const LineData = Gra.getGraphicsByAttr(value, 'attr')
    if (LineData.length !== 0) LineData.forEach(item => Gra.removeGraphic(item))
}


const InitOthA01 = (map, params) => {
    const { defaultCenter, centerList } = params
    if (defaultCenter) map.centerAt(centerList[defaultCenter].center)
}


// 初始化场景特效
const effectOn = (map) => {
    map.addEffect(new mars3d.effect.FogEffect({ enabled: false }))
    map.addEffect(new mars3d.effect.RainEffect({ enabled: false }))
    map.addEffect(new mars3d.effect.SnowEffect({ enabled: false }))
    map.addEffect(new mars3d.effect.SnowCoverEffect({ enabled: false }))
    map.addEffect(new mars3d.effect.BloomEffect({ enabled: false }))
    map.addEffect(new mars3d.effect.BrightnessEffect({ enabled: false }))
    map.addEffect(new mars3d.effect.NightVisionEffect({ enabled: false }))
    map.addEffect(new mars3d.effect.BlackAndWhiteEffect({ enabled: false }))
    map.addEffect(new mars3d.effect.MosaicEffect({ enabled: false }))
    map.addEffect(new mars3d.effect.DepthOfFieldEffect({ enabled: false }))
    map.addEffect(new mars3d.effect.OutlineEffect({ enabled: false }))
    map.addEffect(new mars3d.effect.BloomTargetEffect({ enabled: false }))
}

const GetUrlData = async (url) => {
    return await mars3d.Util.fetchJson({ url: CommonSceneUrl.json + url + '.json' })
}

